package battleship;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Random;

import javax.servlet.http.HttpServletRequest;

public class GameBean {
	final public static int CELL_SIZE = 21;
	final public static int OFFSET_X = 4;
	final public static int OFFSET_Y = 4;
	final public static int PADDING_RIGHT = 8;
	final public static String COORDINATE_SUFFIX = "coords";
	final public static String HIGHLIGHT_COLOUR = "lime";
	final public static String IMAGE_PATH = "ships/";
	final public static String IMAGE_SUFFIX = "image";
	final public static String INPUT_ATTACK_NAME = "attack";
	final public static String ORIENTATION_SUFFIX = "orientation";
	final public static String ORIENTATION_HORIZONTAL = "H";
	final public static String ORIENTATION_VERTICAL = "V";

	private Game g = null;

	public Game getGameObj() {
		return g;
	}

	public static String capitalizeFirst(String s) {
		return Character.toUpperCase(s.charAt(0)) + s.substring(1);
	}

	public static int getCoordX(int x) {
		return (x + 1) * GameBean.CELL_SIZE + GameBean.OFFSET_X;
	}

	public static int getCoordY(int y) {
		return (y + 1) * GameBean.CELL_SIZE + GameBean.OFFSET_Y;
	}

	public static String getImagePath(String name, boolean horizontal) {
		return name
				+ (horizontal ? ORIENTATION_HORIZONTAL : ORIENTATION_VERTICAL)
				+ ".png";
	}

	public void process(HttpServletRequest request)
			throws ClassNotFoundException, IOException, SQLException {
		if (g != null) {
			final String pid = request.getSession()
					.getAttribute(Constants.ATTR_UID).toString();
			if (g.getWinner() == null) {
				if (g.validateSetup(pid)) {
					Connection con = null;

					if (request.getParameter(INPUT_ATTACK_NAME) != null) {
						final String input = request
								.getParameter(INPUT_ATTACK_NAME).toString()
								.toUpperCase();
						final int x = ((int) input.charAt(0)) - 65;
						final int y = Integer.parseInt(input.substring(1));
						if (g.attack(pid, x, y)) {
							con = Database.open();
							final PreparedStatement update = con
									.prepareStatement("update Game set turn=? where gid=?");
							update.setString(1, g.getTurn());
							update.setInt(2, g.gid);
							update.executeUpdate();
						}
					} else if (g.getTurn().equals(Constants.COMPUTER_UID)) {
						final Random generator = new Random();
						int x = generator.nextInt(10);
						int y = generator.nextInt(10);
						while (g.checkAttack(Constants.COMPUTER_UID,x,y)) {
							x = generator.nextInt(10);
							y = generator.nextInt(10);
						}
						
						if (g.attack(Constants.COMPUTER_UID, x, y)) {
							con = Database.open();
							final PreparedStatement update = con
									.prepareStatement("update Game set turn=? where gid=?");
							update.setString(1, g.getTurn());
							update.setInt(2, g.gid);
							update.executeUpdate();
						}
					}

					final String winner = g.getWinner();
					if (winner != null) {
						if (con == null) {
							con = Database.open();
						}
						final PreparedStatement update = con
								.prepareStatement("update Game set winner=? where gid=?");
						update.setString(1, winner);
						update.setInt(2, g.gid);
						update.executeUpdate();
					}

					if (con != null) {
						Database.close(con);
					}
				} else {
					setup(request, pid);
				}
				g.serializeIfChanged();
			}
		}
	}

	private synchronized void setup(HttpServletRequest request, String pid)
			throws ClassNotFoundException, IOException {
		g = Game.unserialize(String.valueOf(g.gid));
		for (final Ship s : Game.ships) {
			final String input = request.getParameter(s.name);
			if (input == null
					|| request.getParameter(s.name + ORIENTATION_SUFFIX) == null
					|| input.length() < 2) {
				break;
			}
			final int x = ((int) input.charAt(0)) - 65;
			final int y = Integer.parseInt(input.substring(1));
			final boolean vertical = request.getParameter(
					s.name + ORIENTATION_SUFFIX).equals(ORIENTATION_VERTICAL);
			g.addShip(pid, s.name, x, y, vertical);
		}
		g.validateSetup(pid);
	}

	public void setGid(String gid) throws ClassNotFoundException, IOException {
		g = Game.unserialize(gid);
	}
}
